package app

import (
	"errors"
	"github.com/gogf/gcache-adapter/adapter"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/os/gfile"
	"strings"
)

/*
	以下Component实现一个服务控制中心实例。
*/

type TOnInit func(*TControlCenterComponent)

type TControlCenterComponent struct {
	Name          string         //实例名称，仅供展示，别无它用
	Version       string         //版本号，仅供展示，别无它用
	HttpSerer     *ghttp.Server  //HTTP服务实例
	MqttClient    TMQTTComponent //MQTT客户端实例
	RSAPublicPem  string         //通讯公钥的PEM文件路径和文件名
	RSAPrivatePem string         //通讯私钥的PEM文件路径和文件名
	RootTopic     string         //消息Topic的根主题（使用多级主题）
	TLSCertFile   string         //TLS的CERT文件路径和文件名
	TLSKeyFile    string         //TLS的KEY文件路径和文件名
	EnableHttps   bool           //是否启用https访问
	EnableRedis   bool           //是否启用Redis
	StaticFolder  string         //静态文件目录
	OnInit        TOnInit        //初始化事件
}

// InitInstance 初始化服务器实例
func (tcc *TControlCenterComponent) InitInstance() {
	//初始化HTTP服务器对象
	tcc.HttpSerer = g.Server()
	//初始化MQTT客户端对象
	tcc.MqttClient.Host = g.Cfg().GetString("mqtt.host")
	tcc.MqttClient.Port = g.Cfg().GetInt("mqtt.port")
	tcc.MqttClient.User = g.Cfg().GetString("mqtt.user")
	tcc.MqttClient.Password = g.Cfg().GetString("mqtt.password")
	er := tcc.MqttClient.InitAndConnect()
	//连接MQTT，触发异常
	if er != nil {
		panic(er)
	}
	//判断是否启用https
	if tcc.EnableHttps == true {
		//如果TLSKeyFile未指定，触发异常
		if strings.TrimSpace(tcc.TLSKeyFile) == "" {
			panic(errors.New("TLS Cert File was empty"))
		}
		if strings.TrimSpace(tcc.TLSCertFile) == "" {
			panic(errors.New("TLS Key File was empty"))
		}
		//如果CERT文件不存在，触发异常
		if gfile.Exists(tcc.TLSCertFile) == false {
			panic(errors.New("TLS Cert file not found"))
		}
		//如果Key文件不存在，触发异常
		if gfile.Exists(tcc.TLSKeyFile) == false {
			panic(errors.New("TLS Key file not found"))
		}
		//启用Https
		tcc.HttpSerer.EnableHTTPS(tcc.TLSCertFile, tcc.TLSKeyFile)
	}
	//订阅MQTT根主题，如果根主题为空，触发异常
	if strings.TrimSpace(tcc.RootTopic) != "" {
		tcc.MqttClient.Sub(tcc.RootTopic + "/#")
	}
	//检查通讯公钥和私钥是否存在，否则触发异常
	if (strings.TrimSpace(tcc.RSAPrivatePem) != "") && (gfile.Exists(tcc.RSAPrivatePem) == true) {
		panic(errors.New("RAS Private pem file not found"))
	}
	if (strings.TrimSpace(tcc.RSAPublicPem) != "") && (gfile.Exists(tcc.RSAPublicPem) == true) {
		panic(errors.New("RAS Public pem file not found"))
	}
	//启用Redis
	if tcc.EnableRedis == true {
		adapterRedis := adapter.NewRedis(g.Redis())
		g.DB().GetCache().SetAdapter(adapterRedis)
	}
	//添加http路由，这里添加的是默认路由
	//GroupApi := tcc.HttpSerer.Group("/api")
	//GroupApi.ALL("/add_new_agent", functions.AddNewAgent) //注册新的AGENT实例

	//执行OnInit事件，此处用于添加URL路由等
	if tcc.OnInit != nil {
		tcc.OnInit(tcc)
	}
}

// RunServer 启动服务器实例
func (tcc *TControlCenterComponent) RunServer() {
	tcc.HttpSerer.Run()
}
